//============================================================================
// Name        : Hal.cpp
// Author      : Cristian Gonzalo Gary Bufadel
// Version     :
// Copyright   : 
// Description :
//============================================================================

using namespace std;

#include <Logger.h>
#include "WorkerSpace.h"

#if defined(__DATE__) && defined(__TIME__)
static const char HAL_BUILT[] = __DATE__ " " __TIME__;
#else
static const char HAL_BUILT[] = "Unknown";
#endif

#define OS "Linux"

#define __HAL__            0
#define __HAL_MINOR__      03
#define __HAL_PATCHLEVEL__ 0
#define CC "gcc"


#include "HttpHeader.h"
#include "signal.h"
#include "Print.h"
#include "WorkerSpaceException.h"
#include "Logger.h"
#include "XmlUtils.h"
//#include "Bayes.h"
//#include "svm.h"


int Logger::init_time = time(NULL);

const unsigned int NUM_INDENTS_PER_SPACE = 2;
#define PIDFILE "/tmp/hal.pid"

int utilsRemovePid() {

	const char *filepath = PIDFILE;

	if (unlink(filepath)) {
		printf("cannot delete pidfile\n");
	}

	return 0;
}

int registerPid() {
	FILE *pid_file;
	const char *filepath = PIDFILE;

	if ((pid_file = fopen(filepath, "w")) == NULL) {
		//HAL_TRACE("Error: I can't log pid of hal");
	}

	fprintf(pid_file, "%i", getpid());
	fclose(pid_file);

	return 0;
}

void halVersion(void) {

	printf("HAL %i.%i.%i\n", __HAL__, __HAL_MINOR__, __HAL_PATCHLEVEL__);
	printf("Built : %s (%s %i.%i.%i)\n", HAL_BUILT, CC, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
	printf("Home  : http://www.seginus.cl\n");
	fflush(stdout);

}

WorkerSpace* workerserver;

void signalExit() {
	/* ignore future signals to properly handle the cleanup */
	signal(SIGTERM, SIG_IGN);
	signal(SIGINT, SIG_IGN);
	signal(SIGHUP, SIG_IGN);

	utilsRemovePid();
	delete workerserver;

	printf("exiting .. :( \n");
	_exit(EXIT_SUCCESS);
}
void signalHandler(int signo, siginfo_t *si, void *context) {
	switch (signo) {
	case SIGTERM:
	case SIGINT:
		signalExit();
		break;
	case SIGHUP:
		signalExit();
		break;
	case SIGBUS:
	case SIGSEGV:
		pthread_exit(NULL);
	default:
		kill(getpid(), signo);
	}

}

void signals() {
	struct sigaction act;
	memset(&act, 0x0, sizeof(act));

	/* allow signals to be handled concurrently */
	act.sa_flags = SA_SIGINFO | SA_NODEFER;
	act.sa_sigaction = &signalHandler;

	sigaction(SIGSEGV, &act, NULL);
	sigaction(SIGBUS, &act, NULL);
	sigaction(SIGHUP, &act, NULL);
	sigaction(SIGINT, &act, NULL);
	sigaction(SIGTERM, &act, NULL);
}

int main(void) {

	/*
	 * Creando el archivo tmp pid para Hal
	 */
	registerPid();

	/*
	 * Asignando la funcion para el manejo de Signals del sistema
	 */
	signals();

	halVersion();
	Logger* logger = new Logger;

	printf("Class size : ==================================\n\n");
	printf("size Socket Class %i bytes \n", sizeof(Socket));
	printf("size WorkerSpace Class %i bytes\n", sizeof(WorkerSpace));
	printf("size HalSocket Class %i bytes\n", sizeof(HalSocket));
	printf("size HalThread Class %i bytes\n", sizeof(HalThread));
	printf("size Logger Class %i bytes\n", sizeof(Logger));
	printf("size XmlUtils Class %i bytes\n", sizeof(XmlUtils));
	printf("size Ambiente Class %i bytes\n", sizeof(Ambiente<WorkerSpace>));
	printf("size Print Class %i bytes\n", sizeof(Print));
	printf("size HttpHeader Class %i bytes\n", sizeof(HttpHeader));
	printf("Datatype size : End ================================\n\n");

//
//	string* get = new string("pagina.rss");
//	string* host = new string("localhost:80");
//

//	HttpHeader* http = new HttpHeader();
//
//	string* asd =  http->toString();
//
//
//	printf("%s \n", asd->c_str());


//	list<string*>* lista = XmlUtils::loadrssFromFile("/home/cristian/workspaceCpp/Hal3/doc/google-reader-subscriptions.xml");
//
//	 list<string*>::iterator it = lista->begin();
//
//	 while (it != lista->end()) {
//		 string* urltmp =  (string*)(*it);
//		 cout << *(string*)(*it) << "\n";
//
//		 	size_t pos;
//		 	pos =  urltmp->find_first_of("//");
//		 	pos = pos+2;
//
//		 	string sub = urltmp->substr(pos);
//
//		 	size_t possub = sub.find_first_of("/");
//
//		 	string host2 = sub.substr(0,possub);
//		 	string get2 = sub.substr(possub);
//
//		 	HttpHeader* header = new HttpHeader(new string(get2), new string(host2));
//
//		 	cout << *(header->toString()) << "\n";
//
//	 		it++;
//	 }

//	delete http;

	//server root@46.102.247.206
//
//	//Creando Server
	workerserver = new WorkerSpace(NULL);
	workerserver->setId(0);
	workerserver->setNombre("Workspace Principal");

//	int rc = pthread_create(workerserver->getThread(), workerserver->getAttr(), WorkerSpace::start, workerserver);
//
//	if (rc) {
//		HAL_ERROR(logger, "No se puede crear hilo del servidor :(");
//	}

	WorkerSpace* worker_temp = new WorkerSpace(workerserver);
	worker_temp->setId(20);

	workerserver->addWorkerSpace(2, 2, worker_temp);
	workerserver->runAllWorkers();

	while(1){
		sleep(2);
	}





/*
	//Creando Clientes

	srand(time(NULL));

	int i;
	for (i = 0; i < 100; i++) {

		WorkerSpace* worker_temp = new WorkerSpace(workerserver);
		worker_temp->setId(i+1);
		int x = rand() %100;
		int y = rand() %100;

		workerserver->addWorkerSpace(x, y, worker_temp);
	}

	i = 0;
	int run = 1;
	while (run) {
		i++;
	//	if (i == 2) workerserver->runAllWorkers();

//		if (i > 4){
//
//			printf("\r");
//			Print::printMatConsola(workerserver,20,20);
//			printf("\033[20A");
//
//			fflush(stdout);
//
//		}

		//if (i == 4) run = 0;
		sleep(1);
	}
*/
	signalExit();


	delete logger;

}
